home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / share / system-config-printer / timedops.py < prev    next >
Encoding:
Python Source  |  2009-05-05  |  6.7 KB  |  202 lines

  1. #!/usr/bin/env python
  2.  
  3. ## Copyright (C) 2008 Red Hat, Inc.
  4. ## Copyright (C) 2008 Tim Waugh <twaugh@redhat.com>
  5.  
  6. ## This program is free software; you can redistribute it and/or modify
  7. ## it under the terms of the GNU General Public License as published by
  8. ## the Free Software Foundation; either version 2 of the License, or
  9. ## (at your option) any later version.
  10.  
  11. ## This program is distributed in the hope that it will be useful,
  12. ## but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. ## GNU General Public License for more details.
  15.  
  16. ## You should have received a copy of the GNU General Public License
  17. ## along with this program; if not, write to the Free Software
  18. ## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19.  
  20. import gobject
  21. import gtk
  22. import subprocess
  23. import threading
  24. from gettext import gettext as _
  25. from debug import *
  26.  
  27. class OperationCanceled(RuntimeError):
  28.     pass
  29.  
  30. class Timed:
  31.     def run (self):
  32.         pass
  33.  
  34.     def cancel (self):
  35.         pass
  36.  
  37. class TimedSubprocess(Timed):
  38.     def __init__ (self, timeout=60000, parent=None, show_dialog=True,
  39.                   **args):
  40.         self.subp = subprocess.Popen (**args)
  41.         self.output = dict()
  42.         self.io_source = []
  43.         self.watchers = 2
  44.         self.timeout = timeout
  45.         self.parent = parent
  46.         self.show_dialog = show_dialog
  47.         for f in [self.subp.stdout, self.subp.stderr]:
  48.             source = gobject.io_add_watch (f,
  49.                                            gobject.IO_IN |
  50.                                            gobject.IO_HUP |
  51.                                            gobject.IO_ERR,
  52.                                            self.watcher)
  53.             self.io_source.append (source)
  54.  
  55.         self.wait_window = None
  56.  
  57.     def run (self):
  58.         if self.show_dialog:
  59.             self.wait_source = gobject.timeout_add (1000,
  60.                                                     self.show_wait_window)
  61.  
  62.         self.timeout_source = gobject.timeout_add (self.timeout,
  63.                                                    self.do_timeout)
  64.         gtk.main ()
  65.         gobject.source_remove (self.timeout_source)
  66.         if self.show_dialog:
  67.             gobject.source_remove (self.wait_source)
  68.         for source in self.io_source:
  69.             gobject.source_remove (source)
  70.         if self.wait_window != None:
  71.             self.wait_window.destroy ()
  72.         return (self.output.get (self.subp.stdout, '').split ('\n'),
  73.                 self.output.get (self.subp.stderr, '').split ('\n'),
  74.                 self.subp.poll ())
  75.  
  76.     def do_timeout (self):
  77.         gtk.main_quit ()
  78.         return False
  79.  
  80.     def watcher (self, source, condition):
  81.         if condition & gobject.IO_IN:
  82.             buffer = self.output.get (source, '')
  83.             buffer += source.read ()
  84.             self.output[source] = buffer
  85.  
  86.         if condition & gobject.IO_HUP:
  87.             self.watchers -= 1
  88.             if self.watchers == 0:
  89.                 gtk.main_quit ()
  90.                 return False
  91.  
  92.         return True
  93.  
  94.     def show_wait_window (self):
  95.         wait = gtk.MessageDialog (self.parent,
  96.                                   gtk.DIALOG_MODAL |
  97.                                   gtk.DIALOG_DESTROY_WITH_PARENT,
  98.                                   gtk.MESSAGE_INFO,
  99.                                   gtk.BUTTONS_CANCEL,
  100.                                   _("Please wait"))
  101.         wait.connect ("delete_event", lambda *args: False)
  102.         wait.connect ("response", self.wait_window_response)
  103.         if self.parent:
  104.             wait.set_transient_for (self.parent)
  105.         wait.set_position (gtk.WIN_POS_CENTER_ON_PARENT)
  106.         wait.format_secondary_text (_("Gathering information"))
  107.         wait.show_all ()
  108.         self.wait_window = wait
  109.         return False
  110.  
  111.     def wait_window_response (self, dialog, response):
  112.         if response == gtk.RESPONSE_CANCEL:
  113.             self.cancel ()
  114.  
  115.     def cancel (self):
  116.         if self.watchers > 0:
  117.             debugprint ("Command canceled")
  118.             gtk.main_quit ()
  119.             self.watchers = 0
  120.  
  121. class OperationThread(threading.Thread):
  122.     def __init__ (self, target=None, args=(), kwargs={}):
  123.         threading.Thread.__init__ (self)
  124.         self.setDaemon (True)
  125.         self.target = target
  126.         self.args = args
  127.         self.kwargs = kwargs
  128.         self.exception = None
  129.         self.result = None
  130.  
  131.     def run (self):
  132.         try:
  133.             debugprint ("Calling %s" % self.target)
  134.             self.result = self.target (*self.args, **self.kwargs)
  135.             debugprint ("Done")
  136.         except Exception, e:
  137.             debugprint ("Caught exception %s" % e)
  138.             self.exception = e
  139.  
  140.     def collect_result (self):
  141.         if self.isAlive ():
  142.             # We've been canceled.
  143.             raise OperationCanceled()
  144.  
  145.         if self.exception:
  146.             raise self.exception
  147.  
  148.         return self.result
  149.  
  150. class TimedOperation(Timed):
  151.     def __init__ (self, target, args=(), kwargs={}, parent=None,
  152.                   show_dialog=False):
  153.         self.wait_window = None
  154.         self.parent = parent
  155.         self.show_dialog = show_dialog
  156.         self.thread = OperationThread (target=target,
  157.                                        args=args,
  158.                                        kwargs=kwargs)
  159.         self.thread.start ()
  160.  
  161.     def run (self):
  162.         if self.show_dialog:
  163.             wait = gtk.MessageDialog (self.parent,
  164.                                       gtk.DIALOG_MODAL |
  165.                                       gtk.DIALOG_DESTROY_WITH_PARENT,
  166.                                       gtk.MESSAGE_INFO,
  167.                                       gtk.BUTTONS_CANCEL,
  168.                                       _("Please wait"))
  169.             wait.connect ("delete_event", lambda *args: False)
  170.             wait.connect ("response", self.wait_window_response)
  171.             if self.parent:
  172.                 wait.set_transient_for (self.parent)
  173.  
  174.             wait.set_position (gtk.WIN_POS_CENTER_ON_PARENT)
  175.             wait.format_secondary_text (_("Gathering information"))
  176.             wait.show_all ()
  177.  
  178.         self.timeout_source = gobject.timeout_add (50, self.check_thread)
  179.         gtk.main ()
  180.         gobject.source_remove (self.timeout_source)
  181.         if self.show_dialog:
  182.             wait.destroy ()
  183.  
  184.         return self.thread.collect_result ()
  185.  
  186.     def check_thread (self):
  187.         if self.thread.isAlive ():
  188.             # Thread still running.
  189.             return True
  190.  
  191.         # Thread has finished.  Stop the sub-loop.
  192.         gtk.main_quit ()
  193.         return False
  194.  
  195.     def wait_window_response (self, dialog, response):
  196.         if response == gtk.RESPONSE_CANCEL:
  197.             self.cancel ()
  198.  
  199.     def cancel (self):
  200.         debugprint ("Command canceled")
  201.         gtk.main_quit ()
  202.